function sum(x: number, y: number): string {
    return x + y + '';
}
sum(1, 2)
//注意：输入多余或者少于的参数，是不被允许的


// 2.函数表达式
let mySum: (x: number, y: number) => number = function (x: number, y: number): number {
    return x + y;
}
mySum(3, 5);
//注：不要混淆了ts中的=>和ES6中的=>；
//在ts的类型定义中，=>表示函数的定义，左边是输入类型，用括号括起来，右边是输出类型


// 3.用接口定义函数的形状
interface SearchFunc {
    (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function (source: string, subString: string) {
    return source.search(subString) !== -1;
}


// 4.可选参数
//与可选属性类似，我们用?表示可选的参数
//注：可选参数必须接在必须参数后面。也就是说可选参数后面不允许再出现必须参数了
function buildName(firstName: string, lastName?: string) {
    if (lastName) {
        return firstName + '' + lastName;
    } else {
        return firstName;
    }
}
let tomact = buildName('Tom', 'Cat');
let tom = buildName('Tom');


// 5.参数默认值
//不受【可选参数必须接在必须参数的后面】的限制
function buildName1(lastName: string = 'Cat', firstName: string) {
    return firstName + '' + lastName;
}
let tomact1 = buildName1('Tom', 'Cat');
let tom1 = buildName1(undefined, 'Tom');

//6.剩余参数
//用...rest的方式获取函数中的生于参数（rest参数）
function push(array: any[], ...items: any[]) {
    items.forEach(function (item) {
        array.push(item);
    })
}
let a: any[] = [];
push(a, 1, 2, 3);

// 7.重载
// 允许一个函数接受不同数量或类型的参数时，作出不同的处理
function reverse(x: number):number;
function reverse(x: string):string;
function reverse(x: number | string):number | string | undefined {
    if (typeof x === 'number') {
        return Number(x.toString().split('').reverse().join(''));
    } else if (typeof x === 'string') {
        return x.split('').reverse().join('');
    }
    return undefined;
}
//如上：我们重复定义了多次函数reverse，前几次都是函数定义，最后一次是函数实现。
//注：ts会从最前面的函数定义开始匹配，所以多个函数如有包含关系，需要优先把精确的定义写在前面
